package com.lysj.admin.master.auth.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.crypto.digest.BCrypt;
import com.lysj.admin.master.auth.domain.User;
import com.lysj.admin.master.auth.mapper.UserMapper;
import com.lysj.admin.master.bussiness.admin.domain.Agent;
import com.lysj.admin.master.bussiness.admin.service.AgentService;
import com.lysj.admin.master.bussiness.company.company.domain.Company;
import com.lysj.admin.master.bussiness.company.company.service.CompanyService;
import com.lysj.admin.master.common.CommonConstant;
import com.lysj.admin.master.common.cache.RedisKeyEnum;
import com.lysj.admin.master.common.cache.RedisUtil;
import com.lysj.admin.master.common.exception.BaseException;
import com.lysj.admin.master.common.jwt.JwtUtil;
import com.lysj.admin.master.common.spring.mpbase.IdEntity;
import com.lysj.admin.master.common.spring.mpbase.MyService;
import com.lysj.admin.master.common.validation.Validation;
import com.lysj.admin.master.common.validation.domain.BindingResult;
import com.lysj.admin.master.common.web.ParamUtil;
import com.lysj.admin.master.common.web.Resp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author Created by zk on 2019-12-04 14:28
 * @description
 */
@Slf4j
@Service
@Transactional
public class UserService extends MyService<UserMapper, User> {

    @Resource
    private RoleService roleService;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private AgentService agentService;
    @Resource
    private CompanyService companyService;

    public String login(String username, String password, String type) {
        User user = this.lambdaQuery()
                .select(IdEntity::getId, User::getPassword, User::getDelFlag)
                .eq(User::getUsername, username)
                .eq(User::getType, type)
                .one();
        if (ParamUtil.isBlank(user)) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "用户名不存在");
        }
        if (user.getDelFlag().equals(CommonConstant.DEL_FLAG)) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "用户已被禁用");
        }
        if (!BCrypt.checkpw(password, user.getPassword())) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "密码错误");
        }
        Map<String, Object> map = new HashMap<>();
        //如果当前登录的为代理商
        if (CommonConstant.AGENT_ISSUER.equals(type)) {
            Agent agent = agentService.lambdaQuery().eq(Agent::getPhone, username).one();
            map.put(CommonConstant.AGENT_ID_NAME, agent.getId());
        }
        //如果当前登录的为用工企业
        if (CommonConstant.COMPANY_ISSUER.equals(type)) {
            Company company = companyService.lambdaQuery().eq(Company::getPhone, username).one();
            map.put(CommonConstant.COMPANY_ID_NAME, company.getId());
        }
        return JwtUtil.createToken(user.getId(), username, type, CommonConstant.ADMIN_TOKEN_EXPIRATION,map);
    }

    public void saveUser(User user, String passwordConfirm) {
        int count = this.lambdaQuery()
                .eq(User::getUsername, user.getUsername())
                .count();
        if (count > 0) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "该用户名已存在");
        }
        if (!user.getPassword().equals(passwordConfirm)) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "密码与确认密码不一致");
        }
        count = roleService.lambdaQuery()
                .eq(IdEntity::getId, user.getRoleId())
                .eq(IdEntity::getDelFlag, CommonConstant.NORMAL_FLAG)
                .count();
        if (count <= 0) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "该角色不存在");
        }
        user.setPassword(BCrypt.hashpw(user.getPassword()));
        save(user);
    }

    public void updateUser(User user) {
        user.setPassword(null);
        user.setUsername(null);
        User u = this.getById(user.getId());
        if (u == null) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "查无此用户");
        }
        //获取Hutool拷贝实例
        CopyOptions copyOptions = CopyOptions.create();
        //忽略为null值得属性
        copyOptions.setIgnoreNullValue(true);
        //进行属性拷贝
        BeanUtil.copyProperties(user, u, copyOptions);
        Set<String> ignoreProperties = new HashSet<>();
        ignoreProperties.add("username");
        ignoreProperties.add("password");
        BindingResult bindingResult = Validation.valid(u, ignoreProperties);
        if (!bindingResult.isFlag()) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, bindingResult.getMessage().get(0));
        }
        updateById(u);
        redisUtil.set(RedisKeyEnum.USER, u.getId(), u);
    }

    public void restPassword(String id) {
        User u = this.getById(id);
        if (u == null) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "查无此用户");
        }
        u.setPassword(BCrypt.hashpw("123456"));
        this.updateUser(u);
    }
}
